#include "GlSection.h"

#include <algorithm>
#include "Utility.h"

namespace GraphicLibrary
{
	//------------------------------------------------------
	void Section::scale(float perc)
	{
		Position nB = lerp(perc);
		Position nE = lerp(1.0f - perc);
		mBegin = nB;
		mEnd = nE;
	}

	//------------------------------------------------------
	bool Section::GetIntersection(const Section &first, const Section &second, Position *intersection)
	{
#		define x1 first.mBegin.mX
#		define x2 first.mEnd.mX
#		define y1 first.mBegin.mY
#		define y2 first.mEnd.mY

#		define X1 second.mBegin.mX
#		define X2 second.mEnd.mX
#		define Y1 second.mBegin.mY
#		define Y2 second.mEnd.mY

		float down = (x1-x2)*(Y1-Y2)-(y1-y2)*(X1-X2);
		if(down == 0.0f)
			return false;
		float up = y2*(X1-X2)-(Y1-Y2)*(x2-X2)-Y2*(X1-X2);
		float b = up / down;

		float a = -1.0f;
		if(Utility::abs(X1-X2) > Utility::abs(Y1-Y2))
			a = (x1*b + x2*(1-b)-X2)/(X1-X2);
		else if(Y1-Y2 != 0.0f)
			a = (y1*b + y2*(1-b)-Y2)/(Y1-Y2);

		*intersection = first.lerp(b);
		return a <= 1.0001f && a >= -0.0001f && b <= 1.0001 && b >= -0.0001f;

#		undef x1
#		undef x2
#		undef y1
#		undef y2

#		undef X1
#		undef X2
#		undef Y1
#		undef Y2
	}
}

namespace GraphicLibrary
{
	//------------------------------------------------------
	void SectionArray::add(const Section &section)
	{
		iterator i = findPlace(section);
		if(i == end() || *i != section)
			insert(i, section);
	}

	//------------------------------------------------------
	void SectionArray::remove(const Section &section)
	{
		iterator i = findPlace(section);
		if(i != end() && *i == section)
			erase(i);
	}

	//------------------------------------------------------
	SectionArray::iterator SectionArray::findPlace(const Section &section)
	{
		class Less
		{
			public:
				inline bool operator () (const Section &left, const Section &right) const	{return memcmp(&left, &right, sizeof(Section)) < 0;}
		};
		return std::lower_bound(begin(), end(), section, Less());
	}
}
